package main

import (
	"bytes"
	"crypto/cipher"
	"crypto/des"
	"encoding/base64"
	"fmt"
)

func DesEncrypt(origData, key []byte) ([]byte, error) {
	block, err := des.NewCipher(key) //加密密码
	if err != nil {
		return nil, err
	}
	origData = ZeroPadding2(origData, block.BlockSize()) //填充位数0
	blockMode := cipher.NewCBCEncrypter(block, key)      //加密模式
	cryped := make([]byte, len(origData))                //加密存储空间
	blockMode.CryptBlocks(cryped, origData)              //加密
	return cryped, nil
}

func DesEncrypt24Bit(origData, key []byte) ([]byte, error) {
	block, err := des.NewTripleDESCipher(key) //加密密码
	if err != nil {
		return nil, err
	}
	origData = ZeroPadding2(origData, block.BlockSize()) //填充位数0
	blockMode := cipher.NewCBCEncrypter(block, key[:8])  //加密模式
	cryped := make([]byte, len(origData))                //加密存储空间
	blockMode.CryptBlocks(cryped, origData)              //加密
	return cryped, nil
}

func DesDecrypt24Bit(crypted, key []byte) ([]byte, error) {
	block, err := des.NewTripleDESCipher(key) //解密密码
	if err != nil {
		return nil, err
	}
	blockMode := cipher.NewCBCDecrypter(block, key[:8]) //解密模式
	origData := make([]byte, len(crypted))              //解密存储空间
	blockMode.CryptBlocks(origData, crypted)            //解密
	origData = ZeroUnPadding2(origData)                 //删除尾部补充0的数据
	return origData, nil
}

func DesDecrypt(crypted, key []byte) ([]byte, error) {
	block, err := des.NewCipher(key) //解密密码
	if err != nil {
		return nil, err
	}
	blockMode := cipher.NewCBCDecrypter(block, key) //解密模式
	origData := make([]byte, len(crypted))          //解密存储空间
	blockMode.CryptBlocks(origData, crypted)        //解密
	origData = ZeroUnPadding2(origData)             //删除尾部补充0的数据
	return origData, nil
}

//AES对称加密，不足128位用0补充

func ZeroPadding2(cipherText []byte, blockSize int) []byte {
	padding := blockSize - len(cipherText)%blockSize //填充的长度
	padText := bytes.Repeat([]byte{'*'}, padding)    //填充0
	return append(cipherText, padText...)            //字节叠加
}

func ZeroUnPadding2(origData []byte) []byte { //删除填充数据

	return bytes.TrimRightFunc(origData, func(r rune) bool {
		return r == rune('*')
	})
}

func test8Bit() {

	fmt.Println("game start")
	key := []byte("yincheng")                           //密码只能8位
	result, err := DesEncrypt([]byte("QQ7705077"), key) //加密
	if err != nil {
		panic(nil)
	}

	fmt.Println(base64.StdEncoding.EncodeToString(result)) //打印加密的数据
	origData, err := DesDecrypt(result, key)               // 解密
	if err != nil {
		panic(err)
	}
	fmt.Println(string(origData))
}

func test24Bit() {

	fmt.Println("game start")
	key := []byte("yincheng0000888899998888")                //
	result, err := DesEncrypt24Bit([]byte("QQ7705077"), key) //加密
	if err != nil {
		panic(nil)
	}

	fmt.Println(base64.StdEncoding.EncodeToString(result)) //打印加密的数据
	origData, err := DesDecrypt24Bit(result, key)          // 解密
	if err != nil {
		panic(err)
	}
	fmt.Println(string(origData))
}

func main() {
	test8Bit()
	test24Bit()
}
